<!--
  Copyright JS Foundation and other contributors, http://js.foundation

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<script type="text/x-red" data-template-name="http request">
    <div class="form-row">
        <label for="node-input-method"><i class="fa fa-tasks"></i> <span data-i18n="httpin.label.method"></span></label>
        <select type="text" id="node-input-method" style="width:70%;">
        <option value="GET">GET</option>
        <option value="POST">POST</option>
        <option value="PUT">PUT</option>
        <option value="DELETE">DELETE</option>
        <option value="use" data-i18n="httpin.setby"></option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label>
        <input id="node-input-url" type="text" placeholder="http://">
    </div>

    <div class="form-row">
        <input type="checkbox" id="node-input-usetls" style="display: inline-block; width: auto; vertical-align: top;">
        <label for="node-input-usetls" style="width: auto" data-i18n="httpin.use-tls"></label>
        <div id="node-row-tls" class="hide">
            <label style="width: auto; margin-left: 20px; margin-right: 10px;" for="node-input-tls"><span data-i18n="httpin.tls-config"></span></label><input type="text" style="width: 300px" id="node-input-tls">
        </div>
    </div>

    <div class="form-row">
        <input type="checkbox" id="node-input-useAuth" style="display: inline-block; width: auto; vertical-align: top;">
        <label for="node-input-useAuth" style="width: 70%;"><span data-i18n="httpin.basicauth"></span></label>
        <div style="margin-left: 20px" class="node-input-useAuth-row hide">
            <div class="form-row">
                <label for="node-input-user"><i class="fa fa-user"></i> <span data-i18n="common.label.username"></span></label>
                <input type="text" id="node-input-user">
            </div>
            <div class="form-row">
                <label for="node-input-password"><i class="fa fa-lock"></i> <span data-i18n="common.label.password"></span></label>
                <input type="password" id="node-input-password">
            </div>
        </div>
    </div>


    <div class="form-row">
        <label for="node-input-ret"><i class="fa fa-arrow-left"></i> <span data-i18n="httpin.label.return"></span></label>
        <select type="text" id="node-input-ret" style="width:70%;">
        <option value="txt" data-i18n="httpin.utf8"></option>
        <option value="bin" data-i18n="httpin.binary"></option>
        <option value="obj" data-i18n="httpin.json"></option>
        </select>
    </div>
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
        <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
    </div>
    <div class="form-tips" id="tip-json" hidden><span data-i18n="httpin.tip.req"></span></div>
</script>

<script type="text/x-red" data-help-name="http request">
    <p>Sends HTTP requests and returns the response.</p>

    <h3>Inputs</h3>
    <dl class="message-properties">
        <dt class="optional">url <span class="property-type">string</span></dt>
        <dd>If not configured in the node, this optional property sets the url of the request.</dd>
        <dt class="optional">method <span class="property-type">string</span></dt>
        <dd>If not configured in the node, this optional property sets the HTTP method of the request.
            Must be one of <code>GET</code>, <code>PUT</code>, <code>POST</code>, <code>PATCH</code> or <code>DELETE</code>.</dd>
        <dt class="optional">headers <span class="property-type">object</span></dt>
        <dd>Sets the HTTP headers of the request.</dd>
        <dt class="optional">cookies <span class="property-type">object</span></dt>
        <dd>If set, can be used to send cookies with the request.</dd>
        <dt class="optional">payload</dt>
        <dd>Sent as the body of the request.</dd>
    </dl>
    <h3>Outputs</h3>
    <dl class="message-properties">
        <dt>payload <span class="property-type">string | object | buffer</span></dt>
        <dd>The body of the response. The node can be configured to return the body
             as a string, attempt to parse it as a JSON string or leave it as a
             binary buffer.</dd>
        <dt>statusCode <span class="property-type">number</span></dt>
        <dd>The status code of the response, or the error code if the request could not be completed.</dd>
        <dt>headers <span class="property-type">object</span></dt>
        <dd>An object containing the response headers.</dd>
        <dt>responseUrl <span class="property-type">string</span></dt>
        <dd>In case any redirects occurred while processing the request, this property is the final redirected url.
            Otherwise, the url of the original request.</dd>
        <dt>responseCookies <span class="property-type">object</span></dt>
        <dd>If the response includes cookies, this propery is an object of name/value pairs for each cookie.</dd>
    </dl>
    <h3>Details</h3>
    <p>When configured within the node, the URL property can contain <a href="http://mustache.github.io/mustache.5.html" target="_blank">mustache-style</a> tags. These allow the
    url to be constructed using values of the incoming message. For example, if the url is set to
    <code>example.com/{{{topic}}}</code>, it will have the value of <code>msg.topic</code> automatically inserted.
    Using {{{...}}} prevents mustache from escaping characters like / & etc.</p>
    <p><b>Note</b>: If running behind a proxy, the standard <code>http_proxy=...</code> environment variable should be set and Node-RED restarted.</p>
    <h4>Using multiple HTTP Request nodes</h4>
    <p>In order to use more than one of these nodes in the same flow, care must be taken with
    the <code>msg.headers</code> property. The first node will set this property with
    the response headers. The next node will then use those headers for its request - this
    is not usually the right thing to do. If <code>msg.headers</code> property is left unchanged
    between nodes, it will be ignored by the second node. To set custom headers, <code>msg.headers</code>
    should first be deleted or reset to an empty object: `{}`.
    <h4>Cookie handling</h4>
    <p>The <code>cookies</code> property passed to the node must be an object of name/value pairs.
    The value can be either a string to set the value of the cookie or it can be an
    object with a single <code>value</code> property.<p>
    <p>Any cookies returned by the request are passed back under the <code>responseCookies</code> property.</p>
    <h4>Content type handling</h4>
    <p>If <code>msg.payload</code> is an Object, the node will automatically set the content type
    of the request to <code>application/json</code> and encode the body as such.</p>
    <p>To encode the request as form data, <code>msg.headers["content-type"]</code> should be set to <code>application/x-www-form-urlencoded</code>.</p>

</script>

<script type="text/javascript">
    RED.nodes.registerType('http request',{
        category: 'function',
        color:"rgb(231, 231, 174)",
        defaults: {
            name: {value:""},
            method:{value:"GET"},
            ret: {value:"txt"},
            url:{value:"",validate:function(v) { return (v.trim().length === 0) || (v.indexOf("://") === -1) || (v.trim().indexOf("http") === 0)} },
            tls: {type:"tls-config",required: false}
        },
        credentials: {
            user: {type:"text"},
            password: {type: "password"}
        },
        inputs:1,
        outputs:1,
        outputLabels: function(i) {
            return ({txt:"UTF8 string", bin:"binary buffer", obj:"parsed JSON object"}[this.ret]);
        },
        icon: "white-globe.png",
        label: function() {
            return this.name||this._("httpin.httpreq");
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        },
        oneditprepare: function() {
            $("#node-input-useAuth").change(function() {
                if ($(this).is(":checked")) {
                    $(".node-input-useAuth-row").show();
                } else {
                    $(".node-input-useAuth-row").hide();
                    $('#node-input-user').val('');
                    $('#node-input-password').val('');
                }
            });
            if (this.credentials.user || this.credentials.has_password) {
                $('#node-input-useAuth').prop('checked', true);
            } else {
                $('#node-input-useAuth').prop('checked', false);
            }
            $("#node-input-useAuth").change();

            function updateTLSOptions() {
                if ($("#node-input-usetls").is(':checked')) {
                    $("#node-row-tls").show();
                } else {
                    $("#node-row-tls").hide();
                }
            }
            if (this.tls) {
                $('#node-input-usetls').prop('checked', true);
            } else {
                $('#node-input-usetls').prop('checked', false);
            }
            updateTLSOptions();
            $("#node-input-usetls").on("click",function() {
                updateTLSOptions();
            });
            $("#node-input-ret").change(function() {
                if ($("#node-input-ret").val() === "obj") {
                    $("#tip-json").show();
                } else {
                    $("#tip-json").hide();
                }
            });
        },
        oneditsave: function() {
            if (!$("#node-input-usetls").is(':checked')) {
                $("#node-input-tls").val("_ADD_");
            }
        }
    });
</script>
